/*
 * Copyright (c) 2005 Chris Richardson
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.chrisrichardson.ormunit.hibernate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.chrisrichardson.util.TxnCallback;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.OrderComparator;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * Does nothing onSetup()/onTearDown() Only executes a transaction when
 * doWithTransaction() is called Use this when you really want the changes
 * committed to the database
 * 
 * @author cer
 * 
 */

public class SimpleHibernatePersistenceTestsStrategy implements
		HibernatePersistenceTestsStrategy, ApplicationContextAware {

	private TransactionTemplate transactionTemplate;

	private List<DatabaseInitializer> databaseInitializers;

	private DatabaseResetStrategy databaseResetStrategy;

	public void onSetUp() {
		databaseResetStrategy.resetDatabase();
        for (DatabaseInitializer initializer : databaseInitializers) {
            initializer.initializeDatabase();
        }
	}

	public void onTearDown() {
	}

	public SimpleHibernatePersistenceTestsStrategy(
			TransactionTemplate transactionTemplate,
			DatabaseResetStrategy databaseResetStrategy) {
		this.transactionTemplate = transactionTemplate;
		this.databaseResetStrategy = databaseResetStrategy;
	}

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        databaseInitializers = new ArrayList<DatabaseInitializer>(applicationContext.getBeansOfType(DatabaseInitializer.class).values());
        Collections.sort(databaseInitializers, new OrderComparator());
        
    }
    
	public void doWithTransaction(final TxnCallback cb) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {

			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					cb.execute();
				} catch (RuntimeException e) {
					throw e;
				} catch (Error e) {
					throw e;
				} catch (Throwable e) {
					throw new RuntimeException(e);
				}
			}
		});
	}

	public int getFlushMode() {
		return HibernateTemplate.FLUSH_AUTO;
	}

    

}
